package com.base.cn.platform.os.common.mybatis;

import org.springframework.util.ObjectUtils;

import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;

/**
 * MyBatis工具类
 * @param <E>
 */
public class MyBatisUtils<E> {
    /**
     * 获取表名
     * @param e
     * @param <E>
     * @return
     */
    public static <E> String getTableName(E e){
        if(!ObjectUtils.isEmpty(e)){
            String tableName = e.getClass().getSimpleName();
            return tableName;
        }
        return "";
    }

    /**
     * 获取类型的所有属性列表
     * @param e
     * @param <E>
     * @return
     */
    public static <E> Field[] getEntityAllField(E e){
        if(!ObjectUtils.isEmpty(e)){
            Field[] fields = MyBatisFieldUtil.getEntityFields(e.getClass(),e);
            return fields;
        }
        return null;
    }

    /**
     * 获取类型的所有属性列表(获取列表中属性最多的元素)
     * @param list
     * @param <E>
     * @return Map<String,Object>
     */
    public static <E> Map<String,Object> getEntityAllField(List<E> list){
        Map<String,Object> map = new HashMap<>();
        list.stream().filter(e->!ObjectUtils.isEmpty(e)).forEach(entity ->{
            Field[] _fields = MyBatisFieldUtil.getEntityFields(entity.getClass(),entity);
            Field[] fs = (Field[])map.get("fields");
            E e = (E)map.get("entity");
            if(fs==null){
                map.put("fields",_fields);
                map.put("entity",entity);
            }else{
                _fields = mergeField(fs,_fields);
                map.put("fields",_fields);
                map.put("entity",entity);
            }
        });
        return map;
    }

    /**
     * 合并属性
     * @param fs
     * @param fields
     * @return
     */
    private static Field[] mergeField(Field[] fs , Field[] fields){
        List<Field> fieldList = Arrays.asList(fs);
        Map<Field,Field> fieldMaps = Arrays.stream(fields).collect(Collectors.toMap(k->k,v->v));
        List<Field> newList = new ArrayList<>();
        fieldList.forEach(e->{
            Field field = fieldMaps.get(e);
            if(field!=null){
                fieldMaps.remove(e);
            }
        });
        newList.addAll(fieldList);
        if(!fieldMaps.isEmpty()){
            newList.addAll(fieldMaps.values());
        }
        return newList.toArray(new Field[newList.size()]);
    }
}
